/**
 * Created by ninemax-199 on 13-12-17.
 */
package authority

import (
	"github.com/astaxie/beego/orm"
	"fmt"
)

type Object struct {
	Id     int64 `form:"-"`
	Name      string `orm:"unique"form:"name,text,名称："`
}
type ObjectInterface interface {
	String() string
}

func (model Object) String() string {
	return fmt.Sprintf("{Id:%d}", model.Id)
}

type Right int

const (
	Browse Right = 1
	Read Right   = 2
	Write Right  = 4
	Exec Right   = 8
	Delete Right = 16

)

type OwnerRights struct {
	Id     int64 `form:"-"`
	Owner *Owner `orm:"rel(fk)"`
	Object *Object `orm:"rel(fk)"`
	Right  Right `orm:"default(0)"`
}
type Owner struct {
	Id     int64 `form:"-"`
	Rights [] *OwnerRights `orm:"reverse(many)"form:"-"`
}
type OwnerInterface interface {
	Authorities(obj *ObjectInterface) []Right
}

type Role  struct {
	Id     int64 `form:"-"`
	Name   string `orm:"unique"form:"name,text,角色名："`
	Owner *Owner `orm:"rel(fk)"`

}
type Group struct {
	Id     int64 `form:"-"`
	Name   string `orm:"unique"form:"name,text,组名称："`
	Owner *Owner `orm:"rel(fk)"`
	Roles  []*Role `orm:"rel(m2m)"form:"-"`
}
type User struct {
	Id              int64 `form:"-"`
	Owner           *Owner `orm:"rel(fk)"`
	Name            string `orm:"unique"form:"name,text,用户名："`
	Compellation    string `form:"compellation,text,姓 名："`
	Gender          bool    `form:"gender,,姓 别："`
	IDCard          string   `form:",text,身份证："`
	Address         string   `form:",text,地 址："`
	ZipCode         string   `form:",text,邮 编："`
	Email           string   `form:",text,Email："`
	QQ              string   `form:",text,QQ："`
	Introduction    string   `form:",text,个人简介："`
	Group           *Group `orm:"rel(fk)"form:"group,select,组名称："`
	Roles           [] *Role `orm:"rel(m2m)"form:"-"`

}

func appendRights(auths []Right , rights []Right) {
	for _ , right := range rights {
		appendRight(auths, right)
	}
}
func appendRight(auths []Right , right Right) {
	if ( right&Browse == Browse) {
		auths = append(auths, Browse)
	}
	if ( right&Read == Read) {
		auths = append(auths, Read)
	}
	if ( right&Write == Write) {
		auths = append(auths, Write)
	}
	if ( right&Exec == Exec) {
		auths = append(auths, Exec)
	}
	if ( right&Delete == Delete) {
		auths = append(auths, Delete)
	}
}

func (role *Role) Authorities(obj *Object) []Right {
	auths := *new([]Right)
	for _, right := range role.Owner.Rights {
		if (right.Object.Id == obj.Id) {
			appendRight(auths, right.Right)
		}
	}
	return auths
}

func (group *Group) Authorities(obj *Object) []Right {
	auths := *new([]Right)
	for _, right := range group.Owner.Rights {
		if (right.Object.Id == obj.Id) {
			appendRight(auths, right.Right)
		}
	}
	for _, role := range group.Roles {
		appendRights(auths, role.Authorities(obj))
	}
	return auths
}

func (user *User) Authorities(obj *Object) []Right {
	auths := *new([]Right)
	for _, right := range user.Owner.Rights {
		if (right.Object.Id == obj.Id) {
			appendRight(auths, right.Right)
		}
	}
	for _, role := range user.Roles {
		appendRights(auths, role.Authorities(obj))
	}
	appendRights(auths, user.Group.Authorities(obj));
	return auths
}

func init() {
	orm.RegisterModel(new(Object), new(Owner), new(OwnerRights), new(Role), new(Group), new(User))
}
